home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / deleteuser / RCS / deleteuser.c,v < prev    next >
Text File  |  1991-12-16  |  24KB  |  1,008 lines

  1. head     1.7;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.7
  10. date     91.12.16.12.10.27;  author kupfer;  state Exp;
  11. branches ;
  12. next     1.6;
  13.  
  14. 1.6
  15. date     91.12.12.12.26.01;  author shirriff;  state Exp;
  16. branches ;
  17. next     1.5;
  18.  
  19. 1.5
  20. date     91.06.04.16.48.40;  author kupfer;  state Exp;
  21. branches ;
  22. next     1.4;
  23.  
  24. 1.4
  25. date     91.06.03.21.46.18;  author kupfer;  state Exp;
  26. branches ;
  27. next     1.3;
  28.  
  29. 1.3
  30. date     91.06.03.16.37.00;  author kupfer;  state Exp;
  31. branches ;
  32. next     1.2;
  33.  
  34. 1.2
  35. date     91.05.31.21.39.35;  author rab;  state Exp;
  36. branches ;
  37. next     1.1;
  38.  
  39. 1.1
  40. date     90.06.22.11.41.53;  author rab;  state Exp;
  41. branches ;
  42. next     ;
  43.  
  44.  
  45. desc
  46. @@
  47.  
  48.  
  49. 1.7
  50. log
  51. @Be less generous with permissions on files.
  52. @
  53. text
  54. @/* 
  55.  * deleteuser.c --
  56.  *
  57.  *    Delete a users account, remove all their files, remove
  58.  *      them from /etc/passwd and take them off the sprite-users
  59.  *      mailing list.
  60.  *      
  61.  * Copyright 1990 Regents of the University of California
  62.  * Permission to use, copy, modify, and distribute this
  63.  * software and its documentation for any purpose and without
  64.  * fee is hereby granted, provided that the above copyright
  65.  * notice appear in all copies.  The University of California
  66.  * makes no representations about the suitability of this
  67.  * software for any purpose.  It is provided "as is" without
  68.  * express or implied warranty.
  69.  */
  70.  
  71. #ifndef lint
  72. static char rcsid[] = "$Header: /sprite/src/admin/deleteuser/RCS/deleteuser.c,v 1.6 91/12/12 12:26:01 shirriff Exp Locker: kupfer $";
  73. #endif /* not lint */
  74.  
  75.  
  76. #include "common.h"
  77. #include <sprite.h>
  78. #include <bstring.h>
  79. #include <errno.h>
  80. #include <fcntl.h>
  81. #include <libc.h>
  82. #include <stdio.h>
  83. #include <stdlib.h>
  84. #include <string.h>
  85. #include <sys/file.h>
  86. #include <sys/ioctl.h>
  87. #include <sys/param.h>
  88. #include <sys/stat.h>
  89. #include <sys/types.h>
  90. #include <sys/wait.h>
  91. #include <unistd.h>
  92.  
  93. /* Forward references: */
  94. static void removeFromMailingLists _ARGS_((CONST char *username));
  95. static void deletePasswdEntry _ARGS_((CONST char *username));
  96. static void removeHomeDirectory _ARGS_((CONST char *homedir));
  97.  
  98.  
  99. /*
  100.  *----------------------------------------------------------------------
  101.  *
  102.  * main --
  103.  *
  104.  *    Process arguments, set uid and signals; then remove users.
  105.  *
  106.  * Results:
  107.  *    None.
  108.  *
  109.  * Side effects:
  110.  *    None.
  111.  *
  112.  *----------------------------------------------------------------------
  113.  */
  114.  
  115. void
  116. main(argc, argv)
  117.     int argc;
  118.     CONST char **argv;
  119. {
  120.     int i;
  121.     CONST char *username;
  122.     struct passwd *pwd;
  123.     char homeDir[MAXPATHLEN];
  124.  
  125.     if(argc < 2 || *argv[1] == '-') {
  126.     (void) fprintf(stderr, "Usage: %s username [username ...]\n", argv[0]);
  127.     (void) fprintf(stderr, "Remove sprite accounts.\n");
  128.     exit(EXIT_FAILURE);
  129.     }
  130. #ifndef TEST
  131.     /* 
  132.      * Verify that we're running as root, so as to avoid unpleasant 
  133.      * surprises later.  Because the program is installed setuid, make 
  134.      * sure that the invoking user is in the wheel group.
  135.      */
  136.     SecurityCheck();
  137. #endif
  138.     printf("This program will delete the accounts and erase\n");
  139.     printf("all the files in the home directories.\n");
  140.     if (!yes("Are you sure you want to do this?")) {
  141.     printf("\nquitting\n");
  142.     exit(EXIT_FAILURE);
  143.     }
  144.     (void) signal(SIGHUP, SIG_IGN);
  145.     (void) signal(SIGINT, SIG_IGN);
  146.     (void) signal(SIGQUIT, SIG_IGN);
  147.     (void) signal(SIGTSTP, SIG_IGN);
  148.  
  149.     /* 
  150.      * For each username, try to get the home directory from the 
  151.      * password file.  If that fails, ask the user if we should 
  152.      * continue (e.g., maybe the user was already removed from the 
  153.      * password file, but not the aliases file).  If the user says to
  154.      * continue, we guess at the home directory.  (XXX We should ask
  155.      * the user.)
  156.      */
  157.     setpwfile(MASTER_PASSWD_FILE);
  158.     if (setpwent() == 0) {
  159.     fprintf(stderr, "Can't change password file to %s\n",
  160.         MASTER_PASSWD_FILE);
  161.     exit(EXIT_FAILURE);
  162.     }
  163.     for (i = 1; i < argc; ++i) {
  164.     username = argv[i];
  165.     if ((pwd = getpwnam(username)) == NULL) {
  166.         fprintf(stderr, "%s: no such user\n", username);
  167.         if (yes("Skip this user?")) {
  168.         continue;
  169.         }
  170.     }
  171.     removeFromMailingLists(username);
  172.  
  173.     /* 
  174.      * If we don't know what the user's home directory is, guess 
  175.      * that it's the default.
  176.      */
  177.     if (pwd != NULL) {
  178.         removeHomeDirectory(pwd->pw_dir);
  179.     } else {
  180.         strcpy(homeDir, USER_DIR);
  181.         strcat(homeDir, "/");
  182.         strcat(homeDir, username);
  183.         removeHomeDirectory(homeDir);
  184.     }
  185.     deletePasswdEntry(username);
  186.     }
  187.     exit(EXIT_SUCCESS);
  188. }
  189.  
  190.  
  191. /*
  192.  *----------------------------------------------------------------------
  193.  *
  194.  *  deletePasswdEntry --
  195.  *
  196.  *      Removes a user's entry from the password file.
  197.  *
  198.  * Results:
  199.  *    none.
  200.  *
  201.  * Side effects:
  202.  *
  203.  *      Exits if there is a system error.
  204.  *
  205.  *----------------------------------------------------------------------
  206.  */
  207. static void
  208. deletePasswdEntry(username)
  209.     CONST char *username;
  210. {
  211.     FILE *tmpfile;
  212.     int fd;
  213.     struct passwd *pwd;
  214.     int found = 0;
  215.     char from[MAXPATHLEN], to[MAXPATHLEN], *tend, *fend;
  216.     char buf1[16], buf2[16];
  217.  
  218.  
  219.     (void) printf("Removing %s from %s.\n", username, MASTER_PASSWD_FILE);
  220.     if ((fd = open(PTMP_FILE, O_CREAT|O_EXCL|O_RDWR, 0600)) < 0) {
  221.     (void) fprintf(stderr, "Cannot open %s: %s\n",
  222.         PTMP_FILE, strerror(errno));
  223.     exit(EXIT_FAILURE);
  224.     }
  225.     if ((tmpfile = fdopen(fd, "w")) == NULL) {
  226.     (void) fprintf(stderr, "Absurd fdopen failure - seek help\n");
  227.     (void) unlink(PTMP_FILE);
  228.     exit(EXIT_FAILURE);
  229.     }
  230.     while ((pwd = getpwent()) != NULL) {
  231.     if (strcmp(pwd->pw_name, username) == 0) {
  232.         ++found;
  233.     } else {
  234.         if (pwd->pw_change==0) {
  235.         *buf1 = '\0';
  236.         } else {
  237.         sprintf(buf1,"%l",pwd->pw_change);
  238.         }
  239.         if (pwd->pw_expire==0) {
  240.         *buf2 = '\0';
  241.         } else {
  242.         sprintf(buf2,"%l",pwd->pw_expire);
  243.         }
  244.         fprintf(tmpfile, "%s:%s:%d:%d:%s:%s:%s:%s:%s:%s\n",
  245.             pwd->pw_name,
  246.             pwd->pw_passwd,
  247.             pwd->pw_uid,
  248.             pwd->pw_gid,
  249.             pwd->pw_class,
  250.             buf1,
  251.             buf2,
  252.             pwd->pw_gecos,
  253.             pwd->pw_dir,
  254.             pwd->pw_shell);
  255.     }
  256.     }
  257.     (void) endpwent();
  258.     (void) fclose(tmpfile);
  259.  
  260.     if (found == 0) {
  261.     (void) fprintf(stderr, "There is no entry for %s in %s.\n",
  262.                username, MASTER_PASSWD_FILE);
  263.     (void) unlink(PTMP_FILE);
  264.     return;
  265.     }
  266.     if (makedb(PTMP_FILE)) {
  267.     (void) fprintf(stderr, "makedb failed!\n");
  268.     exit(EXIT_FAILURE);
  269.     }
  270.  
  271.     /*
  272.      * possible race; have to rename four files, and someone could slip
  273.      * in between them.  LOCK_EX and rename the ``passwd.dir'' file first
  274.      * so that getpwent(3) can't slip in; the lock should never fail and
  275.      * it's unclear what to do if it does.  Rename ``ptmp'' last so that
  276.      * passwd/vipw/chpass can't slip in.
  277.      */
  278.     fend = strcpy(from, PTMP_FILE) + strlen(PTMP_FILE);
  279.     tend = strcpy(to, PASSWD_FILE) + strlen(PASSWD_FILE);
  280.     bcopy(".dir", fend, 5);
  281.     bcopy(".dir", tend, 5);
  282.     if ((fd = open(from, O_RDONLY, 0)) >= 0) {
  283.     (void)flock(fd, LOCK_EX);
  284.     /* here we go... */
  285.     if (rename(from, to)) {
  286.         (void) fprintf(stderr, "Cannot rename %s: %s\n",
  287.         from, strerror(errno));
  288.     }
  289.     bcopy(".pag", fend, 5);
  290.     bcopy(".pag", tend, 5);
  291.     if (rename(from, to)) {
  292.         (void) fprintf(stderr, "Cannot rename %s: %s\n",
  293.         from, strerror(errno));
  294.     }
  295.     }
  296.     bcopy(".orig", fend, 6);
  297.     if (rename(PASSWD_FILE, PASSWD_BAK)) {
  298.     (void) fprintf(stderr, "Cannot rename %s: %s\n",
  299.         from, strerror(errno));
  300.     }
  301.     if (rename(MASTER_PASSWD_FILE, MASTER_BAK)) {
  302.     (void) fprintf(stderr, "Cannot rename %s: %s\n",
  303.         MASTER_PASSWD_FILE, strerror(errno));
  304.     }
  305.     if (rename(from, PASSWD_FILE)) {
  306.     (void) fprintf(stderr, "Cannot rename %s: %s\n",
  307.         PASSWD_FILE, strerror(errno));
  308.     }
  309.     if (rename(PTMP_FILE, MASTER_PASSWD_FILE)) {
  310.     (void) fprintf(stderr, "Cannot rename %s: %s\n",
  311.         PTMP_FILE, strerror(errno));
  312.     }
  313.     return;
  314. }
  315.  
  316.  
  317. /*
  318.  *----------------------------------------------------------------------
  319.  *
  320.  *  removeFromMailingLists --
  321.  * 
  322.  *      Remove a user from all the mailing list.
  323.  *
  324.  * Results:
  325.  *    None.
  326.  *
  327.  * Side effects:
  328.  *      Modifies /sprite/lib/sendmail/aliases.
  329.  *
  330.  *----------------------------------------------------------------------
  331.  */
  332. static void
  333. removeFromMailingLists(username)
  334.     CONST char *username;
  335. {
  336.     int status;            /* exit status from subprocesses */
  337.     char message[4096];        /* log message for "ci" and user prompt */
  338.     
  339.     /* 
  340.      * For the time being, rather than try to get string manipulation 
  341.      * code right, just invoke an editor and let the user remove all 
  342.      * instances of the name.
  343.      */
  344.     sprintf(message, "Remove %s from the aliases file?", username);
  345.     if (!yes(message)) {
  346.     return;
  347.     }
  348.  
  349.     sprintf(message, "-mdeleteuser: remove %s.", username);
  350.     
  351.     status = rcsCheckOut(ALIASES);
  352.     if (status < 0) {
  353.     exit(EXIT_FAILURE);
  354.     } else if (status != 0) {
  355.     goto error;
  356.     }
  357.  
  358.     /* 
  359.      * Give the user ownership of the file, so that she can edit it.
  360.      */
  361.     if (chown(ALIASES, getuid(), -1)  != 0) {
  362.     perror("Can't chown the aliases file");
  363.     goto error;
  364.     }
  365.  
  366.     if (Misc_InvokeEditor(ALIASES) != 0) {
  367.     fprintf(stderr, "Couldn't invoke editor.\n");
  368.     goto error;
  369.     }
  370.  
  371.     /* 
  372.      * Check the aliases file back in, even if we didn't actually make 
  373.      * any changes.
  374.      */
  375.     status = rcsCheckIn(ALIASES, message);
  376.     if (status == 0) {
  377.     printf("Removed %s from aliases file.\n", username);
  378.     } else {
  379.     fprintf(stderr, "\nPlease check the aliases file.\n");
  380.     fprintf(stderr, "(Make sure that `%s' is no longer in any lists\n",
  381.            username);
  382.     fprintf(stderr, "and that the file was checked in.)\n\n");
  383.     }
  384.     return;
  385.  
  386.  error:
  387.     fprintf(stderr,
  388.         "\nWarning: unable to remove `%s' from the aliases file.\n",
  389.         username);
  390.     fprintf(stderr, "You'll have to edit the aliases file by hand.\n\n");
  391.     return;
  392. }
  393.  
  394.  
  395. /*
  396.  *----------------------------------------------------------------------
  397.  *
  398.  * removeHomeDirectory --
  399.  *
  400.  *    Remove a home directory.
  401.  *
  402.  * Results:
  403.  *    None.
  404.  *
  405.  * Side effects:
  406.  *    Deletes all the files in the directory and then unlinks it.  
  407.  *    If the given directory is really a symbolic link, removes the 
  408.  *    link and the directory it points to.
  409.  *
  410.  *----------------------------------------------------------------------
  411.  */
  412. static void
  413. removeHomeDirectory(givenDir)
  414.     CONST char *givenDir;    /* path to the directory, usually a 
  415.                  * link to the real home directory */
  416. {
  417.     char actualDir[MAXPATHLEN]; /* the real home directory */
  418.     char command[MAXPATHLEN + 20]; /* passed to system() */
  419.     struct stat statBuf;
  420.     int n;
  421.  
  422.     if (lstat(givenDir, &statBuf) < 0) {
  423.     fprintf(stderr, "Can't stat %s: %s\n", givenDir,
  424.         strerror(errno));
  425.     return;
  426.     }
  427.     if ((statBuf.st_mode & S_IFMT) == S_IFDIR) {
  428.     strcpy(actualDir, givenDir);
  429.     } else if ((statBuf.st_mode & S_IFMT) == S_IFLNK) {
  430.     n = readlink(givenDir, actualDir, sizeof(actualDir));
  431.     if (n < 0) {
  432.         fprintf(stderr, "Cannot read link %s: %s.\n",
  433.             givenDir, strerror(errno));
  434.         return;
  435.     }
  436.     actualDir[n] = '\0';
  437.     } else {
  438.     fprintf(stderr,
  439.         "%s isn't a link or a directory; not removing.\n", 
  440.         givenDir);
  441.     return;
  442.     }
  443.  
  444.     /* 
  445.      * actualDir now contains the path for the directory we want to 
  446.      * delete.
  447.      */
  448.  
  449.     if ((statBuf.st_mode & S_IFMT) == S_IFLNK) {
  450.     printf("removing symbolic link: %s\n", givenDir);
  451.     if (unlink(givenDir)) {
  452.         (void) fprintf(stderr, "Cannot unlink %s: %s\n",
  453.                givenDir, strerror(errno));
  454.     }
  455.     }
  456.     printf("removing home directory: %s\n", actualDir);
  457.     (void) sprintf(command, "rm -rf %s", actualDir);
  458.     if (system(command) != 0) {
  459.     (void) fprintf(stderr, "Error deleting files from %s.\n", actualDir);
  460.     }
  461.     return;
  462. }
  463. @
  464.  
  465.  
  466. 1.6
  467. log
  468. @Fixed a problem with deleteuser messing up the password file.
  469. @
  470. text
  471. @d19 1
  472. a19 1
  473. static char rcsid[] = "$Header: /sprite/src/admin/deleteuser/RCS/deleteuser.c,v 1.5 91/06/04 16:48:40 kupfer Exp Locker: shirriff $";
  474. d167 1
  475. a167 1
  476.     if ((fd = open(PTMP_FILE, O_CREAT|O_EXCL|O_RDWR, 0660)) < 0) {
  477. @
  478.  
  479.  
  480. 1.5
  481. log
  482. @Make sure the invoking user is in the wheel group.
  483. @
  484. text
  485. @d19 1
  486. a19 1
  487. static char rcsid[] = "$Header: /sprite/src/admin/deleteuser/RCS/deleteuser.c,v 1.4 91/06/03 21:46:18 kupfer Exp Locker: kupfer $";
  488. d163 1
  489. d165 1
  490. d167 1
  491. a167 1
  492.     if ((fd = open(PTMP_FILE, O_CREAT|O_EXCL|O_RDWR, 0644)) < 0) {
  493. d181 21
  494. a201 8
  495.         (void) fprintf(tmpfile, "%s:%s:%d:%d:%s:%s:%s\n",
  496.                    pwd->pw_name,
  497.                pwd->pw_passwd,
  498.                pwd->pw_uid,
  499.                pwd->pw_gid,
  500.                pwd->pw_gecos,
  501.                pwd->pw_dir,
  502.                pwd->pw_shell);
  503. d206 1
  504. d231 11
  505. a241 11
  506.     }
  507.     /* here we go... */
  508.     if (rename(from, to)) {
  509.     (void) fprintf(stderr, "Cannot rename %s: %s\n",
  510.         from, strerror(errno));
  511.     }
  512.     bcopy(".pag", fend, 5);
  513.     bcopy(".pag", tend, 5);
  514.     if (rename(from, to)) {
  515.     (void) fprintf(stderr, "Cannot rename %s: %s\n",
  516.         from, strerror(errno));
  517. @
  518.  
  519.  
  520. 1.4
  521. log
  522. @Have the user manually edit the aliases file, rather than trying to update it automatically.
  523. @
  524. text
  525. @d19 1
  526. a19 1
  527. static char rcsid[] = "$Header: /sprite/src/admin/deleteuser/RCS/deleteuser.c,v 1.3 91/06/03 16:37:00 kupfer Exp Locker: kupfer $";
  528. d77 8
  529. a84 7
  530. #ifndef TEST    
  531.     if (setreuid(0, 0)) {
  532.     (void) fprintf(stderr, "Cannot set uid to root: %s\n", strerror(errno));
  533.     (void) fprintf(stderr, "This program must be installed setuid.\n");
  534.     exit(1);
  535.     }
  536. #endif    
  537. d286 8
  538. @
  539.  
  540.  
  541. 1.3
  542. log
  543. @The aliases file is under RCS control.  Share code with adduser.
  544. Better testing support.  Lots of lint.
  545. @
  546. text
  547. @d19 1
  548. a19 1
  549. static char rcsid[] = "$Header: /sprite/src/admin/deleteuser/RCS/deleteuser.c,v 1.2 91/05/31 21:39:35 rab Exp Locker: kupfer $";
  550. d28 1
  551. d252 1
  552. a252 3
  553.  *      Remove a user from all the mailing lists.  Entries of the form
  554.  *      `username@@machine' will not be removed, but just `username'
  555.  *      will be.
  556. d258 1
  557. a259 2
  558.  *      Modifies /sprite/lib/sendmail/aliases
  559.  *
  560. a265 5
  561.     int found = 0;
  562.     FILE *tmpfile;
  563.     FILE *aliases;
  564.     int fd;
  565.     char line[0x1000];
  566. d267 1
  567. a267 1
  568.     char logMsg[4096];        /* log message for "ci" */
  569. d269 11
  570. a279 2
  571.     (void) printf("Removing %s from mailing lists.\n", username);
  572.     sprintf(logMsg, "-mdeleteuser: remove %s from all lists.", username);
  573. d288 3
  574. a290 60
  575.     /* 
  576.      * Copy the aliases file to a temporary, removing the instances of 
  577.      * the user name. 
  578.      */
  579.     if ((aliases = fopen(ALIASES, "r")) == NULL) {
  580.     (void) fprintf(stderr, "Cannot open %s: %s\n",
  581.                ALIASES, strerror(errno));
  582.     exit(EXIT_FAILURE);
  583.     }
  584.     if ((fd = open(ALIASES_TMP, O_CREAT|O_RDWR, 0644)) < 0) {
  585.     (void) fprintf(stderr, "Cannot open %s: %s\n",
  586.                ALIASES_TMP, strerror(errno));
  587.     exit(EXIT_FAILURE);
  588.     }
  589.     if ((tmpfile = fdopen(fd, "w")) == NULL) {
  590.     (void) fprintf(stderr, "Absurd fdopen failure - seek help\n");
  591.     (void) unlink(ALIASES_TMP);
  592.     exit(EXIT_FAILURE);
  593.     }
  594.     while (fgets(line, sizeof(line), aliases)) {
  595.     int c;
  596.     char *s, *t;
  597.  
  598.     if (strlen(line) >= sizeof(line) - 1) {
  599.         fprintf(stderr, "Line too long in %s\n", ALIASES);
  600.         exit(EXIT_FAILURE);
  601.     }
  602.     if (line[0] != '#' && ((s = strstr(line, username)) != NULL)
  603.         && ((c = s[-1]) == ' ' || c == '\t' || c == ',' || c == ':')) {
  604.         t = s + strlen(username);
  605.             if (*t == ' ' || *t == '\t' || *t == ',' || *t == '\n') {
  606.         while (*t == ' ' || *t == '\t' || *t == ',') {
  607.             ++t;
  608.         } 
  609.         found = 1;
  610.         memmove(s, t, strlen(t) + 1);
  611.         }
  612.     }
  613.     fputs(line, tmpfile);
  614.     }
  615.     fclose(aliases);
  616.     fclose(tmpfile);
  617.  
  618.     /* 
  619.      * If we made any changes, make the temporary file be the new 
  620.      * aliases file.
  621.      */
  622.     if (found) {
  623.     if (unlink(ALIASES)) {
  624.         (void) fprintf(stderr, "Cannot unlink %s: %s.\n",
  625.         aliases, strerror(errno));
  626.         exit(EXIT_FAILURE);
  627.     }
  628.     if (rename(ALIASES_TMP, ALIASES) < 0) {
  629.         (void) fprintf(stderr, "Cannot rename %s: %s\n",
  630.         ALIASES_TMP, strerror(errno));
  631.         exit(EXIT_FAILURE);
  632.     }
  633.     } else {
  634.     (void) unlink(ALIASES_TMP);
  635. d297 1
  636. a297 1
  637.     status = rcsCheckIn(ALIASES, logMsg);
  638. @
  639.  
  640.  
  641. 1.2
  642. log
  643. @Changes for shadow password file and I'm not sure what else (Mike 
  644. checking in for Bob).
  645. @
  646. text
  647. @d19 1
  648. a19 1
  649. static char rcsid[] = "$Header: /sprite/src/admin/deleteuser/RCS/deleteuser.c,v 1.1 90/06/22 11:41:53 rab Exp Locker: rab $";
  650. d23 5
  651. d31 4
  652. a34 3
  653. #include <fcntl.h>
  654. #include <errno.h>
  655. #include <pwd.h>
  656. a35 4
  657. #include <sys/stat.h>
  658. #include <sys/param.h>
  659. #include <sys/ioctl.h>
  660. #include <sys/file.h>
  661. d37 1
  662. d39 4
  663. a42 3
  664. #ifndef __STDC__
  665. #define const
  666. #endif
  667. d44 1
  668. a44 36
  669. #ifdef TEST
  670. #undef  _PATH_PASSWD
  671. #define _PATH_PASSWD       "test/passwd"
  672. #undef  _PATH_PTMP
  673. #define _PATH_PTMP         "test/ptmp"
  674. #undef    _PATH_MASTERPASSWD
  675. #define    _PATH_MASTERPASSWD "test/master.passwd"
  676. #define ALIASES      "test/aliases"
  677. #define TMP_ALIASES  "test/aliases.deleteusers"
  678. #else
  679. #define ALIASES         "/sprite/lib/sendmail/aliases"
  680. #define TMP_ALIASES     "/sprite/lib/sendmail/aliases.deleteusers"
  681. #endif
  682.  
  683. #define PASSWD_BAK          "/etc/passwd.deleteuser.BAK"
  684. #define MASTER_BAK          "/etc/master.deleteuser.BAK"
  685.  
  686. extern int errno;
  687.  
  688. #ifdef __STDC__
  689. static void prompt(const char *question);
  690. static void removeFromMailingLists(const char *username);
  691. static void deletePasswdEntry(const char *username);
  692. static void removeHomeDirectory(const char *homedir);
  693. static int raw_getchar(void);
  694. static int makedb(char *file);
  695. #else
  696. static void prompt();
  697. static void removeFromMailingLists();
  698. static void removeFromSpriteUsers();
  699. static void deletePasswdEntry();
  700. static void removeHomeDirectory();
  701. static int raw_getchar();
  702. static int makedb();
  703. #endif
  704.  
  705. d48 1
  706. a48 1
  707.  * <procName> --
  708. d50 1
  709. a50 1
  710.  *    <description>
  711. d64 1
  712. a64 1
  713.     const char **argv;
  714. d67 1
  715. a67 2
  716.     char homedir[MAXPATHLEN];
  717.     const char *username;
  718. d69 1
  719. d83 6
  720. a88 3
  721.     (void) fprintf(stderr, "This program will delete the accounts and erase\n");
  722.     (void) fprintf(stderr, "all the files in the home directories.\n");
  723.     prompt("Are you sure you want to do this?");
  724. d94 14
  725. d112 3
  726. a114 1
  727.         continue;
  728. d117 13
  729. a129 1
  730.     removeHomeDirectory(pwd->pw_dir);
  731. d135 1
  732. d141 1
  733. a141 1
  734.  *      Removes a user's entry from /etc/passwd.
  735. d154 1
  736. a154 1
  737.     const char *username;
  738. d162 2
  739. a163 2
  740.     (void) printf("Removing %s from %s.\n", username, _PATH_MASTERPASSWD);
  741.     if ((fd = open(_PATH_PTMP, O_CREAT|O_EXCL|O_RDWR, 0644)) < 0) {
  742. d165 1
  743. a165 1
  744.         _PATH_PTMP, strerror(errno));
  745. d170 1
  746. a170 1
  747.     (void) unlink(_PATH_PTMP);
  748. d190 3
  749. a192 3
  750.     (void) fprintf(stderr, "There is no entry for %s in /etc/passwd.\n",
  751.         username);
  752.     (void) unlink(_PATH_PTMP);
  753. d195 1
  754. a195 1
  755.     if (makedb(_PATH_PTMP)) {
  756. a199 1
  757.  
  758. d207 2
  759. a208 2
  760.     fend = strcpy(from, _PATH_PTMP) + strlen(_PATH_PTMP);
  761.     tend = strcpy(to, _PATH_PASSWD) + strlen(_PATH_PASSWD);
  762. d226 1
  763. a226 1
  764.     if (rename(_PATH_PASSWD, PASSWD_BAK)) {
  765. d230 1
  766. a230 1
  767.     if (rename(_PATH_MASTERPASSWD, MASTER_BAK)) {
  768. d232 1
  769. a232 1
  770.         _PATH_MASTERPASSWD, strerror(errno));
  771. d234 3
  772. a236 7
  773.     if (rename(from, _PATH_PASSWD)) {
  774.     (void) fprintf(stderr, "Cannot rename %s: %s\n",
  775.         _PATH_PASSWD, strerror(errno));
  776.     }
  777.     if (rename(_PATH_PTMP, _PATH_MASTERPASSWD)) {
  778.     (void) fprintf(stderr, "Cannot rename %s: %s\n",
  779.         _PATH_PTMP, strerror(errno));
  780. d238 1
  781. a238 1
  782.     if (rename(_PATH_PTMP, _PATH_MASTERPASSWD) < 0) {
  783. d240 1
  784. a240 1
  785.         _PATH_PTMP, strerror(errno));
  786. d245 1
  787. d266 1
  788. a266 1
  789.     const char *username;
  790. d268 1
  791. a268 1
  792.    int found;
  793. d273 12
  794. d286 4
  795. a289 1
  796.     (void) printf("Removing %s from mailing lists.\n", username);
  797. d292 1
  798. a292 1
  799.         ALIASES, strerror(errno));
  800. d295 1
  801. a295 1
  802.     if ((fd = open(TMP_ALIASES, O_CREAT|O_RDWR, 0644)) < 0) {
  803. d297 1
  804. a297 1
  805.         TMP_ALIASES, strerror(errno));
  806. d302 1
  807. a302 1
  808.     (void) unlink(TMP_ALIASES);
  809. d328 5
  810. d339 1
  811. a339 1
  812.     if (rename(TMP_ALIASES, ALIASES) < 0) {
  813. d341 1
  814. a341 1
  815.         TMP_ALIASES, strerror(errno));
  816. d345 15
  817. a359 1
  818.     (void) unlink(TMP_ALIASES);
  819. d362 7
  820. d371 1
  821. d383 3
  822. a385 1
  823.  *    Deletes all the files in the directory and then unlinks it.
  824. d390 3
  825. a392 2
  826. removeHomeDirectory(homedir)
  827.     const char *homedir;
  828. d394 3
  829. a396 2
  830.     char linkbuf[MAXPATHLEN];
  831.     char buf[MAXPATHLEN + 20];
  832. d399 13
  833. a411 7
  834.     if ((n = readlink(homedir, linkbuf, sizeof(linkbuf))) < 0) {
  835.     if (errno == EINVAL) {
  836.         strcpy(buf, homedir);
  837.     } else {
  838.         (void) fprintf(stderr, "Cannot read link to %s: %s.\n",
  839.         homedir, strerror(errno));
  840.         exit(EXIT_FAILURE);
  841. d413 1
  842. d415 4
  843. a418 11
  844. #ifndef TEST    
  845.     printf("removing symbolic link: %s\n", homedir);
  846.     if (unlink(homedir)) {
  847.         (void) fprintf(stderr, "Cannot unlink %s: %s\n",
  848.         homedir, strerror(errno));
  849.         exit(EXIT_FAILURE);
  850.     }
  851. #else    
  852.     printf("unlink(%s)\n", homedir);
  853. #endif    
  854.     linkbuf[n] = '\0';
  855. a419 11
  856.     printf("removing home directory: %s\n", linkbuf);
  857.     (void) sprintf(buf, "rm -rf %s", linkbuf);
  858. #ifndef TEST    
  859.     if (system(buf) != 0) {
  860.     (void) fprintf(stderr, "Error deleting files from %s.\n", linkbuf);
  861.     }
  862. #else
  863.     printf("system(%s)\n", buf);
  864. #endif    
  865.     return;
  866. }
  867. d421 4
  868. a424 23
  869. /*
  870.  *----------------------------------------------------------------------
  871.  *
  872.  * prompt --
  873.  *
  874.  *    Print a prompt, and wait for a yes or no answer.
  875.  *      If the answer is no, then exit with non-zero status.
  876.  *
  877.  * Results:
  878.  *    None.
  879.  *
  880.  * Side effects:
  881.  *    Exits if a negative response is given.
  882.  *
  883.  *----------------------------------------------------------------------
  884.  */
  885. static void    
  886. prompt(question)
  887.     const char *question;
  888. {
  889.     for (;;) {
  890.     (void) fprintf(stderr, "%s (y/n) ", question);
  891.     switch (raw_getchar()) {
  892. d426 5
  893. a430 13
  894.     case 'y':
  895.     case 'Y':
  896.         printf("\n\n");
  897.         break;
  898.  
  899.     case 'n':
  900.     case 'N':
  901.         (void) fprintf(stderr, "\n\nquitting\n");
  902.         exit(EXIT_FAILURE);
  903.  
  904.     default:
  905.         (void) fprintf(stderr, "\n\nPlease enter `y' or `n'.\n");
  906.         continue;
  907. d432 5
  908. a436 1
  909.     break;
  910. a439 51
  911.  
  912. /*
  913.  *----------------------------------------------------------------------
  914.  *
  915.  * raw_getchar --
  916.  *
  917.  *    Get a character in cbreak mode, without waiting for a carriage
  918.  *      return.
  919.  *
  920.  * Results:
  921.  *    Returns the character read, or EOF if no more input is available.
  922.  *
  923.  * Side effects:
  924.  *    None.
  925.  *
  926.  *----------------------------------------------------------------------
  927.  */
  928.  
  929. static int
  930. raw_getchar()
  931. {
  932.     struct sgttyb sgtty_buf;
  933.     int c;
  934.  
  935.     ioctl(0, TIOCGETP, &sgtty_buf);
  936.     sgtty_buf.sg_flags |= CBREAK;
  937.     ioctl(0, TIOCSETP, &sgtty_buf);
  938.     c = getchar();
  939.     sgtty_buf.sg_flags &= ~CBREAK;
  940.     ioctl(0, TIOCSETP, &sgtty_buf);
  941.     return c;
  942. }
  943.  
  944. static int
  945. makedb(file)
  946.         char *file;
  947. {
  948.         int status, pid, w;
  949.  
  950.         if (!(pid = vfork())) {
  951.                 execl(_PATH_MKPASSWD, "mkpasswd", "-p", file, NULL);
  952.                 (void) fprintf(stderr, "Can't exec %s: %s\n",
  953.             _PATH_MKPASSWD, strerror(errno));
  954.                 _exit(127);
  955.         }
  956.         while ((w = wait(&status)) != pid && w != -1) {
  957.         continue;
  958.     }
  959.         return (w == -1 || status);
  960. }
  961.  
  962. @
  963.  
  964.  
  965. 1.1
  966. log
  967. @Initial revision
  968. @
  969. text
  970. @d19 1
  971. a19 1
  972. static char rcsid[] = "$Header$";
  973. d33 2
  974. d41 6
  975. a46 2
  976. #define PTMP         "test/ptmp"
  977. #define PASSWD       "test/passwd"
  978. a49 2
  979. #define PTMP        "/etc/ptmp"
  980. #define PASSWD      "/etc/passwd"
  981. d54 3
  982. d65 1
  983. d73 1
  984. d159 1
  985. d161 4
  986. a164 3
  987.     (void) printf("Removing %s from %s.\n", username, PASSWD);
  988.     if ((fd = open(PTMP, O_CREAT|O_EXCL|O_RDWR, 0644)) < 0) {
  989.     (void) fprintf(stderr, "Cannot open %s: %s\n", PTMP, strerror(errno));
  990. d169 1
  991. a169 1
  992.     (void) unlink(PTMP);
  993. d191 1
  994. a191 1
  995.     (void) unlink(PTMP);
  996. d194 2
  997. a195 3
  998.     if (unlink(PASSWD)) {
  999.     (void) fprintf(stderr, "Cannot unlink %s: %s.\n",
  1000.         PASSWD, strerror(errno));
  1001. d198 47
  1002. a244 3
  1003.     if (rename(PTMP, PASSWD) < 0) {
  1004.     (void) fprintf(stderr, "Cannot rename %s: %s\n", PTMP, strerror(errno));
  1005.     exit(EXIT_FAILURE);
  1006. d462 18
  1007. @
  1008.